/*servertest.c*/
/*assume that the server is machine 0*/
#include "syscall.h"
#include "syscall2.h"

int myLocks[1024];
int myConds[1024];
int myMVs[1024];

int main()
{	
	int i = 0;
	int r=0;
	int c=0;
	int test=0;
	int outputLen = 0;
	char outBuff[32];
	
	ConsoleAcquire();
		Write("Starting signal client...\n",26,ConsoleOutput);
	ConsoleRelease();
	
	Acquire(0);
	Signal(0,0);
	ConsoleAcquire();
		Write("Signal client releasing lock...\n",32,ConsoleOutput);
	ConsoleRelease();
	Release(0);
	
	/*try to create 500 locks*/
	for(i = 0; i < 500; i++)
	{
		myLocks[i] = CreateLock("locky",5);
		ConsoleAcquire();
			Write("Created lock ",14,ConsoleOutput);
			outputLen = Itoa(myLocks[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	
	/*try to acquire each lock*/
	for(i = 0; i < 500; i++)
	{
		Acquire(myLocks[i]);
		ConsoleAcquire();
			Write("Acquired lock ",14,ConsoleOutput);
			outputLen = Itoa(myLocks[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	
	/*try to reacquire each lock*/
	for(i = 0; i < 500; i++)
	{
		Acquire(myLocks[i]);
	}
	
	/*try to release each lock*/
	for(i = 0; i < 500; i++)
	{
		Release(myLocks[i]);
		ConsoleAcquire();
			Write("Released lock ",14,ConsoleOutput);
			outputLen = Itoa(myLocks[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	
	/*try to re-release each lock*/
	for(i = 0; i < 500; i++)
	{
		Release(myLocks[i]);
	}
	
	/*try to create 500 conditions*/
	for(i = 0; i < 500; i++)
	{
		myConds[i] = CreateCondition("cond",4);
		ConsoleAcquire();
			Write("Created cond ",14,ConsoleOutput);
			outputLen = Itoa(myConds[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	
	/*try to destroy all locks and conditions*/
	for(i = 0; i < 500; i++)
	{
		ConsoleAcquire();
			Write("Destroying condition ",21,ConsoleOutput);
			outputLen = Itoa(myConds[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
			ConsoleRelease();
		DestroyCondition(myConds[i]);
		ConsoleAcquire();
			Write("Destroying lock ",16,ConsoleOutput);
			outputLen = Itoa(myLocks[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
			ConsoleRelease();
		DestroyLock(myLocks[i]);
	}
	
	/*recreate locks and conditions*/
	for(i = 0; i < 500; i++)
	{
		myLocks[i] = CreateLock("locky",5);
		ConsoleAcquire();
			Write("Created lock ",14,ConsoleOutput);
			outputLen = Itoa(myLocks[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	for(i = 0; i < 500; i++)
	{
		myConds[i] = CreateCondition("cond",4);
		ConsoleAcquire();
			Write("Created cond ",14,ConsoleOutput);
			outputLen = Itoa(myConds[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	
	/*now destroy them again to clear the server*/
	for(i = 0; i < 500; i++)
	{
		DestroyCondition(myConds[i]);
		DestroyLock(myLocks[i]);
	}
	Write("MV Tests Beginning...\n",22,ConsoleOutput);
	/*create 500 MVs*/
	for(i = 0; i < 500; i++)
	{
		myMVs[i] = CreateMV(11,11);
		ConsoleAcquire();
			Write("Created MV ",11,ConsoleOutput);
			outputLen = Itoa(myMVs[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	
	/*set values for every spot*/
	for(i = 0; i < 500; i++)
	{
		for(r = 0; r < 5; r++)
		{
			for(c = 0; c < 5; c++)
			{
				SetMV(myMVs[i],r,c, (r*32)+c);
			}
		}
	}
	
	/* test that all the values are correct */
	for(i = 0; i < 500; i++)
	{
		for(r = 0; r < 5; r++)
		{
			for(c = 0; c < 5; c++)
			{
				test = GetMV(myMVs[i],r,c);
				if(test != ((r*32)+c))
				{
					ConsoleAcquire();
						Write("Value test failed!\n",19,ConsoleOutput);
						Write("Expected value: ",16,ConsoleOutput);
						outputLen = Itoa((r*32)+c, outBuff);
						Write(outBuff , outputLen, ConsoleOutput);
						Write("\n",1,ConsoleOutput);
						Write("Returned value: ",16,ConsoleOutput);
						outputLen = Itoa(test, outBuff);
						Write(outBuff , outputLen, ConsoleOutput);
						Write("\n",1,ConsoleOutput);
					ConsoleRelease();
					Exit(1);
				}
			}
		}
	}
	
	/* Destroy all the MVs */
	for(i = 0; i < 500; i++)
	{
		DestroyMV(myMVs[i]);
		ConsoleAcquire();
			Write("Destroyed MV ",12,ConsoleOutput);
			outputLen = Itoa(myMVs[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	
	/* Recreate all the MVs */
	for(i = 0; i < 500; i++)
	{
		myMVs[i] = CreateMV(5,5);
		ConsoleAcquire();
			Write("Created MV ",11,ConsoleOutput);
			outputLen = Itoa(myMVs[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	
	/* and destroy again to clean the server */
	for(i = 0; i < 500; i++)
	{
		DestroyMV(myMVs[i]);
		ConsoleAcquire();
			Write("Destroyed MV ",12,ConsoleOutput);
			outputLen = Itoa(myMVs[i], outBuff);
			Write(outBuff , outputLen, ConsoleOutput);
			Write("\n",1,ConsoleOutput);
		ConsoleRelease();
	}
	
	ConsoleAcquire();
		Write("Server test complete!\n",22,ConsoleOutput);
	ConsoleRelease();
	Exit(0);
}
